import json
from locale import str

from elasticsearch import Elasticsearch
from datetime import datetime
from typing import List, Dict, Union, Any
from django.conf import settings

ES_HOST = settings.ES_HOST

es = Elasticsearch([ES_HOST])


class CaseDocument:
    def __init__(self, id: str, case_name: str, case_number: str, case_reason: str, case_type: str,
                 case_type_code: str, court: str, full_text: str, judgment_date: datetime,
                 legal_basis: str, original_link: str, parties: str, publication_date: datetime,
                 region: str, source: str, trial_procedure: str):
        self.id = id
        self.case_name = case_name
        self.case_number = case_number
        self.case_reason = case_reason
        self.case_type = case_type
        self.case_type_code = case_type_code
        self.court = court
        self.full_text = full_text
        self.judgment_date = judgment_date
        self.legal_basis = legal_basis
        self.original_link = original_link
        self.parties = parties
        self.publication_date = publication_date
        self.region = region
        self.source = source
        self.trial_procedure = trial_procedure

    def serialize(self):
        return {
            "id": self.id,
            "case_name": self.case_name,
            "case_number": self.case_number,
            "case_reason": self.case_reason,
            "case_type": self.case_type,
            "case_type_code": self.case_type_code,
            "court": self.court,
            "full_text": self.full_text,
            "judgment_date": self.judgment_date,
            "legal_basis": self.legal_basis,
            "original_link": self.original_link,
            "parties": self.parties,
            "publication_date": self.publication_date,
            "region": self.region,
            "source": self.source,
            "trial_procedure": self.trial_procedure
        }

    @staticmethod
    def create_query_body(search_data: Dict, page_number: int, page_size: int) -> Dict:
        if not isinstance(search_data, dict):
            search_data_dict = json.loads(search_data)
        else:
            search_data_dict = search_data  # 直接使用，因为已经是dict类型
        query_body = {
            "from": (page_number - 1) * page_size,  # 分页起始
            "size": page_size,  # 每页大小
            "query": {
                "bool": {
                    "should": [
                        {
                            "match": {
                                "full_text": search_data_dict["DisputeFocus"]
                            }
                        },
                        {
                            "bool": {
                                "must": [
                                    {
                                        "match": {
                                            "full_text": search_data_dict["CoreFacts"]
                                        }
                                    }
                                ],
                                "should": [
                                    *[
                                        {"multi_match": {
                                            "query": keyword,
                                            "type": "best_fields",
                                            "fields": ["full_text",
                                                       "case_number",
                                                       "case_name",
                                                       "court",
                                                       "region",
                                                       "case_type",
                                                       "case_type_code",
                                                       "source",
                                                       "trial_procedure",
                                                       "parties",
                                                       "case_reason",
                                                       "legal_basis", ],
                                            "tie_breaker": 0.3
                                        }} for keyword in search_data_dict["Keywords"]
                                    ]
                                ],
                                # "should": [
                                #     *[{"match": {"full_text": keyword}} for keyword in search_data_dict["Keywords"]]
                                # ],
                                "minimum_should_match": 3
                            }
                        }
                    ],
                    "minimum_should_match": 1
                }
            }
        }
        return query_body

    # 假设 search_terms 是从前端传来的字符串数组，每个字符串是搜索词

    @staticmethod
    def create_multi_match_query(search_terms: List[str], page_number: int, page_size: int) -> Dict:
        # 创建查询的基本结构
        query_body = {
            "from": (page_number - 1) * page_size,  # 分页起始
            "size": page_size,  # 每页大小
            "query": {
                "bool": {
                    "should": [
                        {
                            "multi_match": {
                                "query": term,
                                "type": "best_fields",
                                "fields": [
                                    "full_text",
                                    "case_number",
                                    "case_name",
                                    "court",
                                    "region",
                                    "case_type",
                                    "case_type_code",
                                    "source",
                                    "trial_procedure",
                                    "parties",
                                    "case_reason",
                                    "legal_basis",
                                ],
                                "tie_breaker": 0.3
                            }
                        } for term in search_terms
                    ],
                    "minimum_should_match": 1
                }
            }
        }

        return query_body

    @staticmethod
    def search_page(search_data: Any, page_number: int = 1, page_size: int = 10, flag: int = 1) -> \
            tuple[list['CaseDocument'], Any]:

        # 判断search_data的类型
        if flag == 1:
            # search_data是字典类型，使用create_query_body构建查询
            query_body = CaseDocument.create_query_body(search_data, page_number, page_size)
        elif flag == 2:
            # search_data是数组类型，使用create_multi_match_query构建查询
            query_body = CaseDocument.create_multi_match_query(search_data, page_number, page_size)

        # query_body = CaseDocument.create_query_body(page_number, page_size, search_data)
        # todo
        response = es.search(index="case_index_1", body=query_body)
        # response = es.search(index="case", body=query_body)
        hits = response['hits']['hits']
        total = response['hits']['total']['value']  # 获取总文档数

        results = []
        for hit in hits:
            source = hit['_source']
            id = hit['_id']  # 提取文档ID
            case = CaseDocument(
                id=id,
                case_name=source.get('case_name', ''),
                case_number=source.get('case_number', ''),
                case_reason=source.get('case_reason', ''),
                case_type=source.get('case_type', ''),
                case_type_code=source.get('case_type_code', ''),
                court=source.get('court', ''),
                full_text=source.get('full_text', ''),
                judgment_date=source.get('judgment_date', ''),
                legal_basis=source.get('legal_basis', ''),
                original_link=source.get('original_link', ''),
                parties=source.get('parties', ''),
                publication_date=source.get('publication_date', ''),
                region=source.get('region', ''),
                source=source.get('source', ''),
                trial_procedure=source.get('trial_procedure', '')
            )
            results.append(case)
        return results, total

    @staticmethod
    def get_by_id(doc_id: str) -> 'CaseDocument':
        response = es.get(index="case_index_1", id=doc_id)
        # response = es.get(index="case", id=doc_id)
        source = response['_source']
        id = response['_id']  # 提取文档ID

        # 创建并返回一个CaseDocument实例
        return CaseDocument(
            id=id,
            case_name=source.get('case_name', ''),
            case_number=source.get('case_number', ''),
            case_reason=source.get('case_reason', ''),
            case_type=source.get('case_type', ''),
            case_type_code=source.get('case_type_code', ''),
            court=source.get('court', ''),
            full_text=source.get('full_text', ''),
            judgment_date=source.get('judgment_date', ''),
            legal_basis=source.get('legal_basis', ''),
            original_link=source.get('original_link', ''),
            parties=source.get('parties', ''),
            publication_date=source.get('publication_date', ''),
            region=source.get('region', ''),
            source=source.get('source', ''),
            trial_procedure=source.get('trial_procedure', '')
        )


if __name__ == '__main__':
    #     str = """{
    #     "DisputeFocus": "房客与房东之间关于房屋漏水问题导致家具损坏的赔偿问题。",
    #     "CoreFacts": "房客在租赁房屋期间，因房东未及时处理房屋内的漏水问题而导致家具损坏。他将房东告上法庭，要求赔偿家具损坏的费用和其他损失。房东辩称，他们已经对房屋进行了定期检查和维护，事故是因为房客自己不小心造成的。",
    #     "Keywords": [
    #         "房屋漏水问题",
    #         "家具损坏",
    #         "赔偿问题",
    #         "租赁房屋",
    #         "定期检查和维护",
    #         "事故原因",
    #         "房客",
    #         "法庭",
    #         "诉讼"
    #     ]
    # }
    #     """
    #     case_page_info = CaseDocument.search_page(str)

    # for case_info in case_page_info:
    #     j = ollama_chat(task_2_prompt.replace("@检索事件@", case_info.full_text).replace("@用户输入@", """
    #     房客在租赁房屋期间，因房东未及时处理房屋内的漏水问题而导致家具损坏。他将房东告上法庭，要求赔偿家具损坏的费用和其他损失。房东辩称，他们已经对房屋进行了定期检查和维护，事故是因为房客自己不小心造成的。"""),
    #                     "11", "gemma:7b")
    #     print(j)
    #     print(len(case_info))
    #     for case in case_info:
    #         print(case.case_name)
    search_terms = ["租赁", "民事案件"]
    case_page_info, total = CaseDocument.search_page(search_terms, 1, 4, 2)
    for case_info in case_page_info:
        print(case_info.case_name)
        print("=====================================")
    print(total)
